/*
 *                        .::::.
 *                      .::::::::.
 *                     :::::::::::
 *                  ..:::::::::::'
 *               '::::::::::::'
 *                 .::::::::::
 *            '::::::::::::::..
 *                 ..::::::::::::.
 *               ``::::::::::::::::
 *                ::::``:::::::::'        .:::.
 *               ::::'   ':::::'       .::::::::.
 *             .::::'      ::::     .:::::::'::::.
 *            .:::'       :::::  .:::::::::' ':::::.
 *           .::'        :::::.:::::::::'      ':::::.
 *          .::'         ::::::::::::::'         ``::::.
 *      ...:::           ::::::::::::'              ``::.
 *     ````':.          ':::::::::'                  ::::..
 *                        '.:::::'                    ':'````..
 */

#include "ssd1306_oled.h"
#include "c081_nfc.h"
#include "iot_i2c.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include <unistd.h>
#include "hi_time.h"
#include "code_tab.h"
#include "app_test_multi_sample.h"

extern hi_u8 g_current_mode;

hi_u8 ndef_file_wechat[1024]= {
    0x00,0x20,
    0xd4, 0x0f,0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
    0x69, 0x64,0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x70,
    0x6b, 0x67,0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65,
    0x6e, 0x63,0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x6d,
};
hi_u8 ndef_file_today_headline[1024] ={
    0x00,0x2d,
    0xd4, 0x0f, 0x1b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 
    0x69, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x70, 
    0x6b, 0x67, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x73,
    0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
    0x2e, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 
    0x2e, 0x6e, 0x65, 0x77, 0x73, 
};
hi_u8 ndef_file_taobao[1024]={
    0x00,0x23, 
    0xd4, 0x0f, 0x11, 0x61, 0x6e, 0x64, 0x72, 0x6f, 
    0x69, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x70, 
    0x6b, 0x67, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x61, 
    0x6f, 0x62, 0x61, 0x6f, 0x2e, 0x74, 0x61, 0x6f, 
    0x62, 0x61, 0x6f,
};
hi_u8 ndef_file_huawei_smart_life[1024]={
    0x00,0x26, 
    0xd4, 0x0f, 0x14, 0x61, 0x6e, 0x64, 0x72, 0x6f, 
    0x69, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x70, 
    0x6b, 0x67, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x75, 
    0x61, 0x77, 0x65, 0x69, 0x2e, 0x73, 0x6d, 0x61, 
    0x72, 0x74, 0x68, 0x6f, 0x6d, 0x65,
};
hi_u8 ndef_file_histreaming[1024]={
    0x00,0x3d,
    0xd4, 0x0f, 0x2b, 0x61, 0x6e, 0x64, 0x72, 0x6f,
    0x69, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x70,
    0x6b, 0x67, 0x61, 0x70, 0x70, 0x6b, 0x69, 0x74,
    0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x6f, 0x75,
    0x72, 0x63, 0x65, 0x2e, 0x67, 0x69, 0x7a, 0x77,
    0x69, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 
    0x6d, 0x79, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 
    0x61, 0x74, 0x69, 0x6f, 0x6e,
};
#define I2C_REG_ARRAY_LEN           (64)
#define OLED_SEND_BUFF_LEN          (28)
#define OLED_SEND_BUFF_LEN2         (25)
#define OLED_SEND_BUFF_LEN3         (27)
#define OLED_SEND_BUFF_LEN4         (29)
#define Max_Column                  (128)
#define OLED_TEST_TASK_STAK_SIZE    (1024*2)
#define OLED_TEST_TASK_PRIORITY     (25)
#define OLED_DISPLAY_INTERVAL_TIME  (1)
#define SEND_CMD_LEN                (2)

extern IotU8_t ndef_file[1024];
extern IotU8_t  g_menu_type;
extern IotU8_t  g_menu_select ;
extern IotU8_t  g_current_mode;
extern IotU8_t  g_current_type;
extern IotU8_t  g_key_down_flag;
extern IotU8_t  g_menu_mode;
extern IotU32_t g_gpio7_first_key_dwon;
static IotU8_t hi3861_board_led_test =0;

/*
    *@bref   向ssd1306 屏幕寄存器写入命令
    *status 0：表示写入成功，否则失败
*/
static IotU32_t i2c_write_byte(IotU8_t reg_addr, IotU8_t cmd)
{
    IotU32_t status =0;
    IotI2cIdx id = IOT_I2C_IDX_0;//I2C 0
    IotU8_t send_len =2;
    IotU8_t user_data = cmd;
    IotI2cData oled_i2c_cmd = { 0 };
    IotI2cData oled_i2c_write_cmd = { 0 };

    IotU8_t send_user_cmd [SEND_CMD_LEN] = {OLED_ADDRESS_WRITE_CMD,user_data};
    IotU8_t send_user_data [SEND_CMD_LEN] = {OLED_ADDRESS_WRITE_DATA,user_data};

    /*如果是写命令，发写命令地址0x00*/
    if (reg_addr == OLED_ADDRESS_WRITE_CMD) {
        oled_i2c_write_cmd.sendBuf = send_user_cmd;
        oled_i2c_write_cmd.sendLen = send_len;
        status = IoTI2cWrite(id, OLED_ADDRESS, oled_i2c_write_cmd.sendBuf, oled_i2c_write_cmd.sendLen);
        if (status != 0) {
            return status;
        }
    }
    /*如果是写数据，发写数据地址0x40*/
    else if (reg_addr == OLED_ADDRESS_WRITE_DATA) {
        oled_i2c_cmd.sendBuf = send_user_data;
        oled_i2c_cmd.sendLen = send_len;
        status = IoTI2cWrite(id, OLED_ADDRESS, oled_i2c_cmd.sendBuf, oled_i2c_cmd.sendLen);
        if (status != 0) {
            return status;
        }
    }

    return 0;
}

/*写命令操作*/
static IotU32_t write_cmd(IotU8_t cmd)//写命令
{
    IotU8_t status =0;
    /*写设备地址*/
	status = i2c_write_byte(OLED_ADDRESS_WRITE_CMD, cmd);
    if (status != 0) {
        return -1;
    }
}
/*写数据操作*/
static IotU32_t write_data(IotU8_t i2c_data)//写数据
{
    hi_u8 status =0;
    /*写设备地址*/
	status = i2c_write_byte(OLED_ADDRESS_WRITE_DATA, i2c_data);
    if (status != 0) {
        return -1;
    }
}
/* ssd1306 oled 初始化*/
IotU32_t oled_init(void)
{
    IotU32_t status;
    hi_udelay(DELAY_100_MS);//100ms  这里的延时很重要

    status = write_cmd(DISPLAY_OFF);//--display off
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SET_LOW_COLUMN_ADDRESS);//---set low column address
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SET_HIGH_COLUMN_ADDRESS);//---set high column address
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SET_START_LINE_ADDRESS);//--set start line address
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SET_PAGE_ADDRESS);//--set page address
    if (status != 0) {
        return -1;
    }
    status = write_cmd(CONTRACT_CONTROL);// contract control
    if (status != 0) {
        return -1;
    }
    status = write_cmd(FULL_SCREEN);//--128
    if (status != 0) {
        return -1;
    }  
    status= write_cmd(SET_SEGMENT_REMAP);//set segment remap
    if (status != 0) {
        return -1;
    } 
    status = write_cmd(NORMAL);//--normal / reverse
    if (status != 0) {
        return -1;
    }
    status =write_cmd(SET_MULTIPLEX);//--set multiplex ratio(1 to 64)
    if (status != 0) {
        return -1;
    }
    status = write_cmd(DUTY);//--1/32 duty
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SCAN_DIRECTION);//Com scan direction
    if (status != 0) {
        return -1;
    }
    status = write_cmd(DISPLAY_OFFSET);//-set display offset
    if (status != 0) {
        return -1;
    }
    status = write_cmd(DISPLAY_TYPE);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(OSC_DIVISION);//set osc division
    if (status != 0) {
        return -1;
    }
    status = write_cmd(DIVISION);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(COLOR_MODE_OFF);//set area color mode off
    if (status != 0) {
        return -1;
    }
    status= write_cmd(COLOR);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(PRE_CHARGE_PERIOD);//Set Pre-Charge Period
    if (status != 0) {
        return -1;
    }
    status = write_cmd(PERIOD);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(PIN_CONFIGUARTION);//set com pin configuartion
    if (status != 0) {
        return -1;
    }
    status = write_cmd(CONFIGUARTION);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SET_VCOMH);//set Vcomh
    if (status != 0) {
        return -1;
    }
    status = write_cmd(VCOMH);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(SET_CHARGE_PUMP_ENABLE);//set charge pump enable
    if (status != 0) {
        return -1;
    }
    status = write_cmd(PUMP_ENABLE);
    if (status != 0) {
        return -1;
    }
    status = write_cmd(TURN_ON_OLED_PANEL);//--turn on oled panel
    if (status != 0) {
        return -1;
    }
    return 0;
}
/*
    @bref set start position 设置起始点坐标
    @param hi_u8 x:write start from x axis
           hi_u8 y:write start from y axis
*/
void oled_set_position(IotU8_t x, IotU8_t y) 
{ 
    write_cmd(0xb0+y);
    write_cmd(((x&0xf0)>>4)|0x10);
    write_cmd(x&0x0f);
}
/*全屏填充*/
void oled_fill_screen(IotU8_t fii_data)
{
    IotU8_t m =0;
    IotU8_t n =0;

    for (m = 0; m < 8; m++) {
        write_cmd(0xb0+m);
        write_cmd(0x00);
        write_cmd(0x10);

        for (n = 0; n < 128; n++) {
            write_data(fii_data);
        }
    }
}

/*
    @bref 8*16 typeface
    @param hi_u8 x:write positon start from x axis 
           hi_u8 y:write positon start from y axis
           hi_u8 chr:write data
           hi_u8 char_size:select typeface
 */
void oled_show_char(IotU8_t x, IotU8_t y, IotU8_t chr, IotU8_t char_size)
{      	
	IotU8_t c=0;
    IotU8_t i=0;

    c = chr-' '; //得到偏移后的值	

    if (x > Max_Column-1) {
        x=0;
        y=y+2;
    }

    if (char_size ==16) {
        oled_set_position(x,y);	
        for(i=0;i<8;i++){
            write_data(F8X16[c*16+i]);
        }
        
        oled_set_position(x,y+1);
        for (i=0;i<8;i++) {
            write_data(F8X16[c*16+i+8]);
        }
        
    } else {	
        oled_set_position(x,y);
        for (i=0;i<6;i++) {
            write_data(F6x8[c][i]);
        }            
    }
}

/*
    @bref display string
    @param hi_u8 x:write positon start from x axis 
           hi_u8 y:write positon start from y axis
           hi_u8 *chr:write data
           hi_u8 char_size:select typeface
*/ 
void oled_show_str(IotU8_t x, IotU8_t y, IotU8_t *chr, IotU8_t char_size)
{
	IotU8_t j=0;

    if (chr == NULL) {
        printf("param is NULL,Please check!!!\r\n");
        return;
    }

	while (chr[j] != '\0') {
        oled_show_char(x, y, chr[j], char_size);
		x += 8;
		if (x>120) {
            x = 0;
            y += 2;
        }
		j++;
	}
}


/*显示主界面*/
void oled_main_menu_display(void)
{
   
    oled_fill_screen(0x00);// clear screen 
    oled_show_str(0,1, "1.Colorful light",1);
    oled_show_str(0,2, "2.Traffic light",1);
    oled_show_str(0,3, "3.Environment",1);
    oled_show_str(0,4, "4.NFC test",1);

    if (g_menu_select == COLORFUL_LIGHT_MENU) {
        oled_show_str(0,7, "Selet:1   Enter",1);
    } else if (g_menu_select == TRAFFIC_LIGHT_MENU) {
        oled_show_str(0,7, "Selet:2   Enter",1);
    } else if (g_menu_select == ENVIRONMENT_MENU) {
        oled_show_str(0,7, "Selet:3   Enter",1);
    } else if (g_menu_select == NFC_TEST_MENU) {
        oled_show_str(0,7, "Selet:4   Enter",1);
    }
}


/*nfc menu display*/
void oled_nfc_display(void)
{
    /*初始化时屏幕 i2c baudrate setting*/
    IoTI2cInit(IOT_I2C_IDX_0, HI_I2C_IDX_BAUDRATE); /* baudrate: 400kbps */
    IoTI2cSetBaudrate(IOT_I2C_IDX_0, HI_I2C_IDX_BAUDRATE);
    /*ssd1306 config init*/
    // oled_init();
    while( 0 != oled_init()) {
         printf("Connecting oled board falied!Please access oled board\r\n");
        if (hi3861_board_led_test == 0) {
            hi3861_board_led_test =1;
             /*test HiSpark board*/
            FACTORY_HISPARK_BOARD_TEST("-----------HiSpark board test----------");  
         }
         task_msleep(SLEEP_1S);
    }
    /*按键中断初始化*/
    test_gpio_init();
    app_multi_sample_test();
    /*display init*/
    oled_fill_screen(OLED_CLEAN_SCREEN);//clear screen 
    oled_show_str(0,0, "WiFi-AP  ON  U:1",1);
    oled_show_str(15,1, "NFC Test",1);
    oled_show_str(0,3, "Mode:          ",1);
    oled_show_str(0,4, "1.NFC Mode     ",1);
    g_menu_select = NFC_TEST_MENU;
    g_menu_mode  =SUB_MODE_SELECT_MODE;
    while (1){
        switch (g_current_mode) {
            case NFC_TAG_WECHAT_MODE:
                oled_show_str(0,4, "1.NFC wechat    ",1);
                oled_show_str(0,5, "                ",1);
                oled_show_str(0,6, "                ",1);
                oled_show_str(0,7, "                ",1);
                memset(ndef_file, 0x00, sizeof(ndef_file));
                memcpy(ndef_file, ndef_file_wechat, sizeof(ndef_file_wechat));
                break;
            case NFC_TAG_TODAY_HEADLINE_MODE:
                oled_show_str(0,4, "2.Today_headlin ",1);
                memset(ndef_file, 0x00, sizeof(ndef_file));
                memcpy(ndef_file, ndef_file_today_headline, sizeof(ndef_file_today_headline));
                break;     
            case NFC_TAG_TAOBAO_MODE:
                oled_show_str(0,4, "3.Taobao        ",1);
                memset(ndef_file, 0x00, sizeof(ndef_file));
                memcpy(ndef_file, ndef_file_taobao, sizeof(ndef_file_taobao));
                break;
            case NFC_TAG_HUAWEI_LIFE_MODE:
                oled_show_str(0,4, "4.Huawei_SM_life",1);
                memset(ndef_file, 0x00, sizeof(ndef_file));
                memcpy(ndef_file, ndef_file_huawei_smart_life, sizeof(ndef_file_huawei_smart_life));
                break;
            case NFC_TAG_HISTREAMING_MODE:
                oled_show_str(0,4, "5.Histreaming   ",1);
                memset(ndef_file, 0x00, sizeof(ndef_file));
                memcpy(ndef_file, ndef_file_histreaming, sizeof(ndef_file_histreaming));
                break;
            case NFC_RETURN_MODE:
                oled_show_str(0,4, "Return Menu     ",1);
                oled_show_str(0,6, "                ",1);
#ifdef  CONFIG_NFC 
                oled_show_str(0,7, "Continue        ",1);
#elif   CONFIG_ALL_TEST
                oled_show_str(0,7, "Continue   Exit ",1);                 
                return_main_enum_sample();
                if (g_current_type == KEY_DOWN) {
                    g_current_mode = MAIN_FUNCTION_SELECT_MODE;
                    oled_main_menu_display();                    
                    return;
                }
                g_current_mode = MAIN_FUNCTION_SELECT_MODE;
#endif                 
                break;               
        default:
            break;
        }
        task_msleep(SLEEP_20_MS);//20ms
    }
}

